package ro.upt.ac.cstaicu.instrumentation.logging;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.TreeSet;

import ro.upt.ac.cstaicu.analyze.Entity;
import ro.upt.ac.cstaicu.execution.TestResult;
import ro.upt.ac.cstaicu.instrumentation.Predicate;


public class PredicateCounterLogger implements GlobalLogger {

	private static PredicateCounterLogger instance;
	
	private TreeSet<Entity> currentPredicates;
//	private HashMap<String, TreeSet<Entity>> predicates;
	private Collection<Entity> predicates = new TreeSet<Entity>();

	private int called;

	private ArrayList<TestResult> results = new ArrayList<TestResult>();

	private PredicateCounterLogger() {
		
	}
	
	public static PredicateCounterLogger getInstance() {
		if (instance == null)
			instance = new PredicateCounterLogger();
		return instance;
	}
	 
	@Deprecated
	public void setPredicates() {
		
	}
	
	@Override
	public Collection<Entity> endLogging() {
//		System.out.println("RESULTS: "+ called + " ");
//		ArrayList<Entity> entities = new ArrayList<Entity>();
//		for (String methodName : predicates.keySet()) {
//			System.out.println("In method " + methodName);
//			for (Entity predicate : predicates.get(methodName))
//				entities.add(predicate);
//				System.out.println(predicate);
//		System.out.println();
//		}
//		return entities;
		return predicates;
	}
	
	public void functionEnded() {};
	
	@Override
	public void logFunctionCall(String className, String methodName,
			ArrayList<MethodParameter> parameters) {
		// TODO Auto-generated method stub
		
	}
	
	public void logPredicate(int predicateID, int opcode, int lineNo, boolean value) {
		called++;
//		for (String methodName : predicates.keySet()) {
//			for (Entity predicate : predicates.get(methodName))
		for (Entity predicate : predicates)
			if (predicate.context.getId() == predicateID) {
				currentPredicates.add(predicate);
				return;
			}
	};
	
	public void setResult(TestResult result) {
		//TODO remove this
		results.add(result);
		if (currentPredicates != null)
		for (Entity predicate : currentPredicates)
			predicate.addTestResult(result);
//		if (result.result == Executor.TEST_PASSED)
//			for (Entity predicate : currentPredicates)
//				predicate.passedTests++;
//		else 
//			for (Predicate predicate : currentPredicates)
//				predicate.failedTests++;
	};
	
	public void setRunningTime(long time) {};
	
	@Override
	public void startLogging(String fileName) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void testStarted(String className, String methodName) {
		currentPredicates = new TreeSet<Entity>();
		
	}

	@Deprecated
	public void setPredicates(HashMap<String, ArrayList<Predicate>> predicates) {
//		this.predicates = new HashMap<String, TreeSet<Entity>>();
//		for (String methodName : predicates.keySet()) {
//			TreeSet<Entity> currentPred = new TreeSet<Entity>();
//			for (Predicate predicate : predicates.get(methodName))
//				currentPred.add(new Entity(predicate, Entity.PREDICATE, methodName, 1));
//			this.predicates.put(methodName, currentPred);
//		}
//		System.out.println(this.predicates);
	}
	
	public ArrayList<TestResult> getResults() {
		return results ;
	}
	
	@Override
	public void addAllEntities(Collection<Entity> tracedPredicates) {
//		if (tracedPredicates != null)
			for (Entity e : tracedPredicates)
				predicates.add(e);
	}
	
	@Override
	public void clearPredicates() {
		predicates.clear();
		results.clear();
	}
	
}
